package com.rainsoftware.LicenseSystem.services;

import com.rainsoftware.LicenseSystem.models.entity.LicenseKey;
import com.rainsoftware.LicenseSystem.models.entity.Product;
import com.rainsoftware.LicenseSystem.utils.StandardResponse;
import gaarason.database.appointment.OrderBy;
import gaarason.database.appointment.Paginate;
import gaarason.database.contract.eloquent.Builder;
import gaarason.database.contract.eloquent.Record;
import gaarason.database.contract.eloquent.RecordList;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class LicenseKeyService {

    @Autowired
    private LicenseKey.Model licenseKeyModel;

    @Autowired
    private Product.Model productModel;

    @Autowired
    UserService userService;

    public StandardResponse generateLicenseKey(String product_api_id, Long duration, Integer amount) {
        Record<Product, Integer> productRecord = productModel.newQuery().where("api_id", product_api_id).first();
        if (productRecord == null) {
            return new StandardResponse(false, HttpStatus.BAD_REQUEST, "产品不存在", null);
        }
        if (duration == null || duration <= 0) {
            return new StandardResponse(false, HttpStatus.BAD_REQUEST, "时长错误，必须是正整数", null);
        }
        if (amount == null || amount <= 0) {
            return new StandardResponse(false, HttpStatus.BAD_REQUEST, "数量错误，必须是正整数", null);
        }

        LicenseKey tempKey = null;
        for (int i = 0; i < amount; i++) {
            Record<LicenseKey, Integer> record = licenseKeyModel.newRecord();
            LicenseKey licenseKey = record.getEntity();
            licenseKey.setProductId(productRecord.getEntity().getId());
            licenseKey.setDeveloperId(userService.getSystemUser().getId());
            licenseKey.setDuration(duration);
            licenseKey.setMachine("");
            licenseKey.setLicenseKey(LicenseKey.generateUniqueKey());
            licenseKey.setActivated(false);
            record.save();
            if (tempKey == null)
                tempKey = licenseKey;
        }

        // 更新产品的密钥数量
        productRecord.getEntity().setActivationCount(
                productRecord.getEntity().getActivationCount() + amount
        );

        return new StandardResponse(true, HttpStatus.OK, "生成成功", tempKey.toJson());
    }

    public StandardResponse deleteLicenseKeys(Map<String, Object> payload) {
        String action = (String) payload.get("action");
        List<Integer> keys = (List<Integer>) payload.get("keys");

        if ("delete".equals(action)) {
            if (keys == null || keys.isEmpty()) {
                return new StandardResponse(true, HttpStatus.BAD_REQUEST, "keys不可为空", null);
            }
            RecordList<LicenseKey, Integer> recordList = licenseKeyModel.newQuery()
                    .where("developer_id", userService.getSystemUser().getId())
                    .whereIn("id", keys)
                    .get();

            HashMap<Integer, Integer> pending_deletion = new HashMap<>();
            for (Record<LicenseKey, Integer> record : recordList) {
                record.delete();
                int pid = record.getEntity().getProductId();

                pending_deletion.put(pid, pending_deletion.getOrDefault(pid, 0) + 1);

            }

            pending_deletion.forEach((k,v) -> {
                Record<Product, Integer> record = productModel.newQuery().first();
                if (record != null) {
                    record.getEntity().setActivationCount(
                            record.getEntity().getActivationCount() - v
                    );
                    record.save();
                }
            });
            return new StandardResponse(true, HttpStatus.OK, "删除成功", null);
        }
        return new StandardResponse(false, HttpStatus.BAD_REQUEST, "请求参数不正确", null);
    }

    public StandardResponse queryLicenseKeys(
            int productId,
            String sort,
            int rows,
            int page,
            String search_for) {
        int devID = userService.getSystemUser().getId();

        Builder<LicenseKey, Integer> builder = productId == -1 ?
                licenseKeyModel.newQuery().where("developer_id", devID) :
                licenseKeyModel.newQuery().where("developer_id", devID).where("product_id", productId);

        if ("created_at".equals(sort)) {
            builder = builder.orderBy("created_at", OrderBy.DESC);
        } else if ("activated_at".equals(sort)) {
            builder = builder.orderBy("activated_at", OrderBy.DESC);
        }

        if (rows > 100) {
            return new StandardResponse(false, HttpStatus.BAD_REQUEST, "每次请求的行数不得超过100", null);
        }

        // 先从产品表中查找出相似的name
        if (search_for != null && !search_for.isEmpty()) {
            RecordList<Product, Integer> productRecord = productModel.newQuery()
                    .where("developer_id", devID)
                    .whereLike("name", String.format("%%%s%%", search_for)).get();
            if (productRecord.isEmpty()) {
                //没找到产品，直接返回空
                return new StandardResponse(true, HttpStatus.OK, "查询成功",
                        new JSONObject()
                                .put("keys", new JSONArray())
                                .put("total_page", 1)
                                .put("current_page", 1));
            }
            List<Integer> list = new ArrayList<>();
            for (Record<Product, Integer> r : productRecord) {
                list.add(r.getEntity().getId());
            }
            builder = builder.whereIn("product_id", list);
        }

        Paginate<LicenseKey> paginate = builder.paginate(page, rows);
        HashMap<Integer, String> cache = new HashMap<Integer, String>();

        JSONArray jsonArray = new JSONArray();
        for (LicenseKey record : paginate.getItemList()) {
            if (cache.get(record.getProductId()) == null) {
                Record<Product, Integer> productRecord = productModel.find(record.getProductId());
                if (productRecord != null) {
                    cache.put(record.getProductId(), productRecord.getEntity().getName());
                } else {
                    cache.put(record.getProductId(), "未知产品");
                }
            }
            jsonArray.put(record.toJson().put("product_name", cache.get(record.getProductId())));
        }

        return new StandardResponse(true, HttpStatus.OK, "查询成功",
                new JSONObject()
                        .put("keys", jsonArray)
                        .put("total_page", paginate.getLastPage())
                        .put("current_page", paginate.getCurrentPage()));
    }

    public StandardResponse handleLicenseKeyAction(int id, String action) {
        if ("delete".equals(action)) {
            Record<LicenseKey, Integer> record = licenseKeyModel.newQuery()
                    .where("developer_id", userService.getSystemUser().getId())
                    .whereIn("id", id)
                    .first();
            if (record != null) {
                // 删除的的时候更新产品密钥数量
                Record<Product, Integer> productRecord = productModel.find(record.getEntity().getProductId());
                if (productRecord != null) {
                    productRecord.getEntity().setKeyCount(
                            productRecord.getEntity().getKeyCount() - 1
                    );
                    productRecord.save();
                }
                record.delete();
                return new StandardResponse(true, HttpStatus.OK, "密钥删除成功", null);
            } else {
                return new StandardResponse(true, HttpStatus.NOT_FOUND, "密钥未找到", null);
            }
        } else {
            return new StandardResponse(false, HttpStatus.BAD_REQUEST, "请求不正确", null);
        }
    }
}